import { Action, Selector, State, StateContext, Store } from '@ngxs/store';
import { catchError, map } from 'rxjs/operators';
import { NzMessageService } from 'ng-zorro-antd/message';
import { LogOutAction, SetTokenAction, SetUserInfoAction } from './auth.action';
import { AuthService } from '../../services/auth.service';
import { Injectable } from '@angular/core';
import { LoginModel } from '../../models/auth.model';
import { Navigate } from '@ngxs/router-plugin';

export interface LoginStateModel {
    login: LoginModel;
    userMenu: any;
    saveLoadingState: boolean;
    userName: string;
    avatar: string;
    token: string;
}

@State<LoginStateModel>({
    name: '_AuthState',
    defaults: {
        login: {} as LoginModel,
        userMenu: null,
        saveLoadingState: false,
        userName: null,
        avatar: null,
        token: localStorage.getItem('token')
    }
})
@Injectable()
export class AuthState {
    constructor(private _authService: AuthService, private _nzMessageService: NzMessageService, private _store: Store) {}

    @Selector()
    public static saveLoadingState(state: LoginStateModel) {
        return state.saveLoadingState;
    }

    @Selector()
    public static userName(state: LoginStateModel) {
        return state.userName;
    }

    @Selector()
    public static avatar(state: LoginStateModel) {
        return state.avatar;
    }



    @Selector()
    public static token(state: LoginStateModel) {
        return state.token;
    }




    @Action(SetUserInfoAction)
    SetUserInfoAction( ctx: StateContext<LoginStateModel>, action: SetUserInfoAction) {
       ctx.patchState({
           avatar: action.avatar
       });
    }

    @Action(SetTokenAction)
    SetTokenAction( ctx: StateContext<LoginStateModel>, action: SetTokenAction) {
       ctx.patchState({
           token: action.token
       });
    }

    /**
     * 退出登录
     * @param ctx StateContext
     * @param action 触发的动作
     */
    @Action(LogOutAction)
    LogOutAction(ctx: StateContext<LoginStateModel>, action: LogOutAction) {
        return this._authService.logOut().pipe(
            map((res) => {
                if (res.code === 200) {
                    sessionStorage.clear();
                    this._store.dispatch(new Navigate(['/login']));
                }
            }),
            catchError((error) => {
                this._nzMessageService.create('error', error);
                throw new Error(error);
            })
        );
    }
}
